package com.sample.dubbo.demo.provider.storage;

import com.sample.dubbo.demo.dto.Customer;
import com.sample.dubbo.demo.exceptions.BusinessException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

@Component
public class CustomerRAMStorage {
    Logger logger = LoggerFactory.getLogger(CustomerRAMStorage.class);

    @Value("${mode:ok}")
    private String mode;
    @Value("${timeout:1000}")
    private Integer timeout;
    @Value("${query.timeout:1000}")
    private Integer queryTimeout;

    private final ConcurrentHashMap<Long, Customer> data = new ConcurrentHashMap();

    {
        for (long i = 1000000; i < 1000100; i++) {
            Customer customer = Customer.createById(i);
            data.put(i, customer);
        }
    }

    public Customer save(Customer customer) {
        check();
        data.put(customer.getId(), customer);
        logger.info("save customer to ram");
        return customer;
    }

    public List<Customer> list() {
        check();
        try {
            Thread.sleep(queryTimeout);
        } catch (InterruptedException e) {
        }
        List<Customer> customers = new ArrayList<>();
        customers.addAll(data.values());
        logger.info("list customer from ram");
        return customers;
    }

    public Customer get(Long id) {
        check();
        Customer customer = data.get(id);
        logger.info("find customer from ram");
        return customer;
    }

    public boolean delete(Long id) {
        check();
        Customer customer = data.remove(id);
        logger.info("delete customer from ram");
        return customer != null;
    }

    private void check() {
        if ("error".equals(mode)) {
            logger.error("服务器端处理异常");
            throw new BusinessException("error_mode", "服务器端处理异常");
        }
        try {
            Thread.sleep(timeout);
        } catch (InterruptedException e) {
        }
    }
}
